package com.zking.controller;

import com.zking.entity.Customent;
import com.zking.repository.CustomentRepsitory;
import com.zking.util.CheckUtil;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.validation.Valid;

@RestController
@RequestMapping("/customent")
public class CustomentController {
    //@Valid 注解校验
    private final CustomentRepsitory customentRepsitory;

    public CustomentController(CustomentRepsitory customentRepsitory){
        this.customentRepsitory=customentRepsitory;
    }

    /**
     * 以SSE形式多次返回数据
     * @return
     */
    @GetMapping(value = "/list",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<Customent> queryCustoment(){
        return customentRepsitory.findAll();

    }
    /**
     * 以数组形式多次返回数据
     * @return
     */
    @GetMapping(value = "/list2")
    public Flux<Customent> queryCustoment2(){
        return customentRepsitory.findAll();

    }

    /**
     * 添加方法
     * @param customent
     * @return
     */
    @PostMapping("/add")
    public Mono<Customent> addCustoment(@Valid @RequestBody Customent customent){
        //spring data jpa新增和修改都是save
        customent.setId(null);
        return customentRepsitory.save(customent);
    }

    /**
     * 删除 如果有数据返回200 没有数据返回404
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    public Mono<ResponseEntity<Void>> del(@PathVariable(value = "id") Integer id){
        //deleteByid没有返回值 不能使用它
        //this.customentRepsitory.deleteById(id);
       return this.customentRepsitory.findById(id)
        //当你要操作数据，并返回一个Mono这个时候使用flatmap
        //如果不操作数据，只是转换数据，使用map
        .flatMap(customent -> this.customentRepsitory.delete(customent)
        .then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK))))
        .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));

    }

    /**
     * 修改数据
     * @param id
     * @param customent
     * @return
     */
    @PutMapping("/update")
    public Mono<ResponseEntity<Customent>> update(
            @PathVariable("id") Integer id,
            @RequestBody Customent customent){
        CheckUtil.checkName(customent.getName());
        return this.customentRepsitory.findById(id)
                //flatmap操作数据
                .flatMap(customent1 -> {
                    customent1.setAge(customent1.getAge());
                    customent1.setName(customent1.getName());
                    customent1.setSex(customent1.getSex());
                    return this.customentRepsitory.save(customent1);

                })
                //map转换数据
                .map(customent1 -> new ResponseEntity<Customent>(customent1,HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    /**
     * 更具id 查找用户
     * @return
     */
    @GetMapping("/{id}")
    public Mono<ResponseEntity<Customent>>findCustomentById(

            @PathVariable(value = "id") Integer id
    ){
        return this.customentRepsitory.findById(id)
                .map(u->new ResponseEntity<Customent>(u,HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<Customent>(HttpStatus.NOT_FOUND));
    }

    /**
     * 更具年龄查找用户
     * @param start
     * @param end
     * @return
     */
    @GetMapping(value = "/age/{start}/{end}")
    public Flux<Customent> findByAge(
            @PathVariable(value = "start")int start,
            @PathVariable(value = "end")int end
                                       ){
     return this.customentRepsitory.findByAgeBetween(start,end);
    }

    /**
     * 更具年龄查找用户
     * @param start
     * @param end
     * @return
     */
    @GetMapping(value = "/stream/age/{start}/{end}",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<Customent> streamFindByAge(
            @PathVariable(value = "start")int start,
            @PathVariable(value = "end")int end
    ){
        return this.customentRepsitory.findByAgeBetween(start,end);
    }
}
